SPB Git forge
7commits 1branches 0releases
229.0 KBsize
maindefault branch
12 days agolast push
TypeScript 91.8% HTML 3.2% JavaScript 3% SQL 1.4% CSS 0.7%
1.7 KB · 29 lines typescript
Raw Blame History
1import { cookies } from "next/headers";2import { NextResponse, type NextRequest } from "next/server";3import { COOKIE, verifyToken } from "@/lib/auth";45export const dynamic = "force-dynamic";6const API_URL = process.env.API_URL ?? "http://127.0.0.1:8350";7const API_TOKEN = process.env.SRC_API_TOKEN ?? "";89/** Authenticated pass-through to the control-plane API (adds the server token, streams SSE as-is). */10async function forward(req: NextRequest, path: string[]) {11  const jar = await cookies();12  if (!verifyToken(jar.get(COOKIE)?.value)) return NextResponse.json({ error: "unauthorized" }, { status: 401 });13  const target = new URL(`/api/${path.join("/")}`, API_URL);14  target.search = req.nextUrl.search;15  const headers: Record<string, string> = { "x-src-token": API_TOKEN };16  if (req.headers.get("content-type")) headers["content-type"] = req.headers.get("content-type")!;17  const upstream = await fetch(target, { method: req.method, headers, body: req.method === "GET" || req.method === "HEAD" ? undefined : await req.text(), cache: "no-store", // @ts-expect-error — undici option for streaming request bodies18    duplex: "half" });19  const ct = upstream.headers.get("content-type") ?? "application/json";20  return new Response(upstream.body, { status: upstream.status, headers: { "content-type": ct, "cache-control": "no-store", ...(ct.includes("event-stream") ? { connection: "keep-alive", "x-accel-buffering": "no" } : {}) } });21}2223export async function GET(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {24  return forward(req, (await ctx.params).path);25}26export async function POST(req: NextRequest, ctx: { params: Promise<{ path: string[] }> }) {27  return forward(req, (await ctx.params).path);28}29